﻿/*
 * Created by SharpDevelop.
 * User: t_furu
 * Date: 2007/11/07
 * Time: 10:33
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.ComponentModel;
using System.Diagnostics;

namespace nicosb.Lib
{
	/// <summary>
	//外部プロセス起動クラス
	/// </summary>
	public class Process
	{
		private System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo();
		private String results = "";
		private System.Diagnostics.Process p = null;
		
		public Process():this(""){
		}
		
		public Process(String Arguments)
		{
			setArguments(Arguments);
			
			//ComSpecのパスを取得する
			psi.FileName = System.Environment.GetEnvironmentVariable("ComSpec");

			//出力を読み取れるようにする
			psi.RedirectStandardInput = false;
			psi.RedirectStandardOutput = true;
			psi.UseShellExecute = false;
			
			//ウィンドウを表示しないようにする
			psi.CreateNoWindow = true;
		}
		
		//コマンドラインを指定
		public void setArguments(String Arguments){
			//コマンドラインを指定（"/c"は実行後閉じるために必要）
			//Arguments = @"/c "dir c:\ /w";
			psi.Arguments = @"cmd /c " + Arguments;
			
			Trace.WriteLine(psi.Arguments);
		}
		
		//コマンドライン実行
		public Boolean start(){
			return start(true);
		}
		
		//コマンドライン実行
		public Boolean start(Boolean wait_flg){
			if(p != null){
				//前回の処理が終了していない
				Trace.WriteLine("Process start cancel");
				return false;
				//Trace.WriteLine("Process start WaitForExit");
				//p.WaitForExit();
			}
			
			//起動
			p = System.Diagnostics.Process.Start(psi);

		    p.EnableRaisingEvents = true;
		    p.Exited += new EventHandler(p_Exited);
		    
			//wait_flg:false 終了待ちをしない
			if(wait_flg) {
				//実行結果出力を読み取る
				results = p.StandardOutput.ReadToEnd();
				p.WaitForExit();
			}
			
			return true;
		}
		
		private void p_Exited(object sender, EventArgs e){
		    //プロセスが終了したときに実行される
		    Trace.WriteLine("Process Exit");
		    stop();
		}

		//終了
		public void stop(){
			Trace.WriteLine(GC.GetTotalMemory(false));
			if(p==null)return;
			try{
				p.Kill();
			}
			catch (Exception e){
				String msg = e.Message;
				//Console.WriteLine(msg);
			}
			finally {
				p.Close();
    			p.Dispose();
				p=null;
			}
			GC.Collect();
			Trace.WriteLine(GC.GetTotalMemory(false));
		}
		
		//実行結果出力を返す
		public String getResults(){
			return results;
		}
	}
}
